<template>
  <div class="box">
    <h1>
      <img :src="store.VideoReciver.Avatar" class="nav-my-img" />
    </h1>
    <div class="container">
      <video ref="videoA" autoplay playsinline></video>
      <div class="container-small">
        <video id="videoASmall" ref="videoASmall" autoplay playsinline></video>
      </div>
      <div id="layerA" class="layer" ref="layerA">
        <div class="layer__text">正在等待对方接受邀请...</div>
      </div>
      <div id="hangupLayer" class="layer" ref="hangupLayer">
        <div class="layer__text">通话已挂断</div>
      </div>
    </div>
    <div class="footer">
      <button id="hangupBtn" @click="hangup" class="hangup-btn">挂断</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, watch, computed } from "vue";
import { useMainStore } from "../store/index";
const store:any = useMainStore();
const layerA = ref<HTMLElement | null>(null);
const videoA = ref<HTMLVideoElement | null>(null);
const videoASmall = ref<HTMLVideoElement | null>(null);
const hangupLayer = ref<HTMLElement | null>(null);
const socket = store.socket
const roomId = computed(() => store.VideoReciver.Id); // 使用computed减少不必要的计算

let streamA: MediaStream | null = null;
let calling = false;
let communicating = false;

onMounted(() => {
  calling = true;
  if (layerA.value) layerA.value.style.display = 'flex';
  if (hangupLayer.value) hangupLayer.value.style.display = 'none';
  init();
});

async function init() {
  if (store.isVideoShow && videoA.value && videoASmall.value) {
    try {
      streamA = await getLocalStream();
      videoA.value.srcObject = streamA;
      videoA.value.play();
      videoASmall.value.srcObject = streamA; // 将本地视频流赋值给 videoASmall
      videoASmall.value.play();
      socket.emit('callEvent', roomId.value);
    } catch (error) {
      console.error('获取本地音视频流失败:', error);
    }
  }
}

socket.on('connectionSuccess', () => {
  console.log('连接成功,发送人进入接收人房间')
  socket.emit('joinRoomEvent', roomId.value);
});

let peer: RTCPeerConnection | null = null;

socket.on('acceptCallEvent', async () => {
  if (layerA.value) layerA.value.style.display = 'none';
  peer = new RTCPeerConnection();
  if (streamA) {
    streamA.getTracks().forEach(track => peer.addTrack(track, streamA));
  }
  peer.onicecandidate = event => {
    if (event.candidate) {
      socket.emit('candidateEvent', { roomId: roomId.value, candidate: event.candidate });
    }
  };
  peer.ontrack = event => {
    calling = false;
    if (layerA.value) layerA.value.style.display = 'none';
    communicating = true;
    if (videoASmall.value) {
      videoASmall.value.srcObject = event.streams[0]; // 将远程视频流赋值给 videoASmall
      setTimeout(() => videoASmall.value.play(), 100);
    }
  };
  try {
    const offer = await peer.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true });
    await peer.setLocalDescription(offer);
    socket.emit('offerEvent', { roomId: roomId.value, offer });
  } catch (error) {
    console.error('创建或设置本地描述失败:', error);
  }
});

socket.on('answerEvent', (answer: RTCSessionDescriptionInit) => {
  if (peer) peer.setRemoteDescription(answer);
});

socket.on('candidateEvent', async (candidate: RTCIceCandidateInit) => {
  if (peer) {
    try {
      await peer.addIceCandidate(candidate);
    } catch (error) {
      console.error('Failed to add ICE candidate:', error);
    }
  }
});
socket.on('end', () => {
  console.log("发送方收到挂断消息")
  if (hangupLayer.value) hangupLayer.value.style.display = 'flex';
  closeStream();
});

function hangup() {
  store.isVideoShow = false;
  closeStream();
  console.log(roomId.value)
  socket.emit('end', roomId.value)
}

async function getLocalStream() {
  try {
    return await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
  } catch (error) {
    console.error('获取本地音视频流失败:', error);
    return null;
  }
}

function closeStream() {
  if (streamA) {
    streamA.getTracks().forEach(track => track.stop());
    streamA = null;
  }
  if (videoA.value) videoA.value.srcObject = null;
  if (videoASmall.value) videoASmall.value.srcObject = null;
}

watch(() => store.isVideoShow, (newValue) => {
  if (!newValue) closeStream();
});
</script>

<style scoped lang="less">
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  background-color: #f5f5f5;
}

.box {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  width: 100%;
  max-width: 400px;

  h1 {
    margin: 20px 0;
    display: flex;
    justify-content: center;
    width: 100%;

    .nav-my-img {
      height: 64px;
      width: 64px;
      border-radius: 50%;
      border: 2px solid #fff;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
  }
}

.container {
  width: 100%;
  height: 480px;
  background-color: #000;
  position: relative;
  overflow: hidden;
  border-radius: 10px 10px 0 0;

  video {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .container-small {
    width: 120px;
    height: 160px;
    position: absolute;
    right: 10px;
    bottom: 10px;
    z-index: 1;
    border-radius: 5px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  }

  .layer {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.8);
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    display: none;

    &__text {
      font-size: 18px;
      margin-bottom: 20px;
    }
  }
}

.footer {
  display: flex;
  justify-content: center;
  padding: 20px 0;
  width: 100%;

  .hangup-btn {
    width: 120px;
    height: 48px;
    cursor: pointer;
    background-color: #ff4d4f;
    border: none;
    border-radius: 24px;
    color: #fff;
    font-size: 16px;
    font-weight: bold;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    transition: background-color 0.3s, transform 0.3s;

    &:hover {
      background-color: #ff7875;
      transform: scale(1.05);
    }

    &:active {
      background-color: #d9363e;
      transform: scale(0.95);
    }
  }
}
</style>